#pragma once

#include <vector>
#include <string>
#include <array>
#include <unordered_map>

/**
 * @brief 网格模型类
 * 
 * 用于处理角点网格模型数据，包括：
 * 1. 读取和解析角点网格文件
 * 2. 存储网格节点和单元信息
 * 3. 提供网格数据访问接口
 */
class GridModel {
public:
    /**
     * @brief 网格尺寸结构体
     */
    struct GridSize {
        int Nx;  ///< X方向网格数量
        int Ny;  ///< Y方向网格数量
        int Nz;  ///< Z方向网格数量
    };

    /**
     * @brief 坐标系变换参数结构体
     */
    struct MapAxes {
        double yAxisX, yAxisY;  ///< Y轴上的点坐标
        double originX, originY;  ///< 原点坐标
        double xAxisX, xAxisY;  ///< X轴上的点坐标
    };

    /**
     * @brief 构造函数
     */
    GridModel() = default;

    /**
     * @brief 从文件加载角点网格数据
     * @param filename 角点网格文件路径
     */
    void loadFromFile(const std::string& filename);

    /**
     * @brief 获取网格尺寸
     * @return 网格尺寸结构体
     */
    const GridSize& getGridSize() const { return gridSize; }

    /**
     * @brief 获取坐标系变换参数
     * @return 坐标系变换参数结构体
     */
    const MapAxes& getMapAxes() const { return mapAxes; }

    /**
     * @brief 获取COORD数据
     * @return COORD数据向量
     */
    const std::vector<double>& getCoordData() const { return coordData; }

    /**
     * @brief 获取ZCORN数据
     * @return ZCORN数据向量
     */
    const std::vector<double>& getZcornData() const { return zcornData; }

    /**
     * @brief 获取ACTNUM数据
     * @return ACTNUM数据向量
     */
    const std::vector<int>& getActnumData() const { return actnumData; }

    /**
     * @brief 将大地坐标转换为角点网格坐标
     * @param x 大地坐标X
     * @param y 大地坐标Y
     * @return 转换后的坐标对
     */
    std::pair<double, double> transformCoordinates(double x, double y) const;

private:
    GridSize gridSize;  ///< 网格尺寸
    MapAxes mapAxes;  ///< 坐标系变换参数
    std::vector<double> coordData;  ///< COORD数据
    std::vector<double> zcornData;  ///< ZCORN数据
    std::vector<int> actnumData;  ///< ACTNUM数据

    /**
     * @brief 解析MAPAXES数据
     * @param line 包含MAPAXES数据的行
     */
    void parseMapAxes(const std::string& line);

    /**
     * @brief 解析SPECGRID数据
     * @param line 包含SPECGRID数据的行
     */
    void parseSpecGrid(const std::string& line);

    /**
     * @brief 解析数值数据
     * @param line 包含数值的行
     * @param target 目标数据向量
     */
    void parseNumericData(const std::string& line, std::vector<double>& target);

    /**
     * @brief 解析ACTNUM数据
     * @param line 包含ACTNUM数据的行
     */
    void parseActnum(const std::string& line);
}; 